﻿using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Linq.Expressions;
using System.Reflection;
using System.Text;
using System.Web;

namespace CommTest.Generic
{
    public class ReflectClass
    {
        public class TestC
        {
            public int Id { get; set; }
            public string Name { get; set; }
            public Guid Type { get; set; }
            private TestC() { }
        }
        public class FieldExpressionVisitor : ExpressionVisitor
        {
            private StringBuilder _sb = new StringBuilder();

            public FieldExpressionVisitor(Expression node)
            {
                Visit(node);
            }

            public string GetField()
            {
                return _sb.ToString();
            }

            protected override Expression VisitMember(MemberExpression node)
            {
                var name = node.Member.Name;
                _sb.Append(name);
                return base.VisitMember(node);
            }
        }

        public static void Test()
        {
            var dic1 = ToDictionary(new Dictionary<string, string>());
            var dic2 = ToDictionary(new { a = 1, b = DateTime.Now, c = "| ?/" });


            TestGetPropName();
            TestAnonymousObject();
            TestConstruction();
            TestOverloadMethod();

            var str1 = ToQuery(new { a = 1, b = DateTime.Now, c = "| ?/" });
            var str2 = ToQuery(new Search() { A = 1 });

            var str3 = JsonConvert.SerializeObject(new { a = 1, b = DateTime.Now });

        }

        public static void TestGetPropName()
        {
            Expression<Func<TestC, string>> expression = testc => testc.Id.ToString();
            Expression<Func<TestC, string>> expression2 = testc => testc.Name;
            var visitor = new FieldExpressionVisitor(expression);
            var field = visitor.GetField();

            var fieldName = new FieldExpressionVisitor(expression2).GetField();
            //ExpressionVisitor.VisitLambda(expression);
        }



        public static void TestAnonymousObject()
        {
            var obj = new { Prop1 = 1, Prop2 = new List<TestC>(), Prop3 = "Hello" };
            var type = obj.GetType();
            var props = type.GetProperties();
            var fields = type.GetFields();
        }

        public static void TestConstruction()
        {
            var con = typeof(TestC).GetConstructors(BindingFlags.NonPublic | BindingFlags.Instance);
            var mmm = typeof(TestC).GetMethods(BindingFlags.NonPublic | BindingFlags.Instance);
            var testInstance = Activator.CreateInstance(typeof(TestC), true);
        }

        public static void TestOverloadMethod()
        {
            var type = typeof(AnyMethods);

            try
            {
                var m1 = type.GetMethod("Test");
            }
            catch (Exception ex)
            {
            }
            var m2 = type.GetMethod("Test", new[] { typeof(int) });
            var m3 = type.GetMethod("Test", new[] { typeof(int), typeof(int) });
        }


        public static string ToQuery(object data)
        {
            string str = string.Empty;

            if (data == null)
            {
                return str;
            }


            Type type = data.GetType();
            System.Reflection.PropertyInfo[] propertyInfos = type.GetProperties();

            foreach (var prop in propertyInfos)
            {
                if (prop.CanRead)
                {
                    str += "&" + prop.Name + "=";
                    var value = prop.GetValue(data, null);
                    if (value != null)
                    {
                        str += HttpUtility.UrlEncode(value.ToString());
                    }
                }
            }
            return str;
        }


        public static Dictionary<string, string> ToDictionary(object data)
        {
            Dictionary<string, string> dic = new Dictionary<string, string>();
            if (data == null)
            {
                return dic;
            }

            Type type = data.GetType();
            if (typeof(Dictionary<string, string>).IsAssignableFrom(type))
            {
                return data as Dictionary<string, string>;
            }

            System.Reflection.PropertyInfo[] propertyInfos = type.GetProperties();
            foreach (var prop in propertyInfos)
            {
                if (!prop.CanRead)
                {
                    continue;
                }

                var value = prop.GetValue(data, null);
                if (value != null)
                {
                    dic.Add(prop.Name, value.ToString());
                }
            }
            return dic;

        }


        public static void Build()
        {
            Type type = typeof(Clac<Num>);

            var contructors = type.GetConstructors();

            var dic = new Dictionary<string, Num>();
            Type typeDic = typeof(Dictionary<,>);

            var types = new Type[] { typeof(string), typeof(Num) };
            var obj = typeDic.MakeGenericType(types);

            var method = dic.GetType().GetMethod("Add");

            var s = method.Invoke(dic, new object[] { "123", new Num() });


        }

    }
}
